package com.zzyl.service.impl;

import com.google.common.collect.Lists;
import com.zzyl.constant.Constants;
import com.zzyl.dto.UserLoginRequestDto;
import com.zzyl.entity.Member;
import com.zzyl.mapper.MemberMapper;
import com.zzyl.properties.JwtTokenManagerProperties;
import com.zzyl.service.MemberService;
import com.zzyl.service.WeChatService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.utils.StringUtils;
import com.zzyl.vo.LoginVo;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 *  微信小程序登录业务
 */

@Service
public class MemberServiceImpl implements MemberService {

    //用户持久层
    @Autowired
    private MemberMapper memberMapper;

    //封装获取 openid、phone API的工具类
    @Autowired
    private WeChatService weChatService;

    //JWT令牌配置类
    @Autowired
    private JwtTokenManagerProperties jwtTokenManagerProperties;

    //为首次登录的用户生成随机名字
    static ArrayList DEFAULT_NICKNAME_PREFIX = Lists.newArrayList(
            "生活更美好",
            "大桔大利",
            "日富一日",
            "好柿开花",
            "柿柿如意",
            "一椰暴富",
            "大柚所为",
            "杨梅吐气",
            "天生荔枝"
    );


    /**
     * 微信小程序登录
     * @param userLoginRequestDto 用户信息
     * @return 登录用户 令牌、昵称
     */
    @Override
    public LoginVo login(UserLoginRequestDto userLoginRequestDto) {

        //1、调用微信工具类接口，获取 openId 【通过code换取openId】
        String openId = weChatService.getOpenid(userLoginRequestDto.getCode());

        //2、根据 openId 查询用户信息
        Member member = memberMapper.getByOpenId(openId);

        //3、判断用户是否存在 -- 不存在创建用户对象 && 赋值 openId
        if (ObjectUtil.isEmpty(member)) {
            member = new Member();
            member.setOpenId(openId);
        }

        //4、调用微信工具类接口，获取 phone 【通过code换取phone】
        String phone = weChatService.getPhone(userLoginRequestDto.getPhoneCode());

        //5、更新或保存用户信息【下方已封装】
        saveOrUpdate(member, phone);

        //6、生成 Token 令牌
        //封装载荷信息
        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.JWT_USERID, member.getId());       //用户Id
        claims.put(Constants.JWT_USERNAME, member.getName());   //用户昵称
        //生成令牌
        String token = JwtUtil.createJWT(jwtTokenManagerProperties.getBase64EncodedSecretKey(),
                                         jwtTokenManagerProperties.getTtl(),
                                         claims);
        //令牌封装到响应数据
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setNickName(member.getName());

        //7、返回数据
        return loginVo;

    }


    /**
     * 保存或修改客户信息
     *
     * @param member 用户 openid
     * @param phone 用户 phone
     */
    private void saveOrUpdate(Member member, String phone) {

        //1.判断取到的手机号与数据库中保存的手机号是否一样【防止用户更换手机号】
        if(ObjectUtil.notEqual(phone, member.getPhone())){
            //设置手机号
            member.setPhone(phone);
        }

        //2.判断id是否存在，存在则更新信息
        if (ObjectUtil.isNotEmpty(member.getId())) {
            memberMapper.update(member);
            return;
        }

        //3.保存新的用户
        //自动生成昵称：随机词组+手机号后四位
        String nickName = DEFAULT_NICKNAME_PREFIX.get((int) (Math.random() * DEFAULT_NICKNAME_PREFIX.size()))
                          + StringUtils.substring(member.getPhone(), 7);
        //设置昵称
        member.setName(nickName);
        //保存信息【insert】
        memberMapper.save(member);

    }




}
